<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <h1 data-lake-id="YjImH" id="YjImH"><span data-lake-id="u937b028b" id="u937b028b">典型回答</span></h1>
  <p data-lake-id="ub4f38837" id="ub4f38837"><br></p>
  <p data-lake-id="u1c5f651d" id="u1c5f651d"><span data-lake-id="u17dc694f" id="u17dc694f">Java中线程的状态分为6种：</span></p>
  <p data-lake-id="u42b3546c" id="u42b3546c"><span data-lake-id="uc3267d3f" id="uc3267d3f">1.初始(NEW)：新创建了一个线程对象，但还没有调用start()方法。</span></p>
  <p data-lake-id="u97137c16" id="u97137c16"><span data-lake-id="u2c9d37fb" id="u2c9d37fb">2.运行(RUNNABLE)：Java线程中将就绪（READY）和运行中（RUNNING）两种状态笼统的称为“运行”。</span></p>
  <p data-lake-id="ubfd1cb53" id="ubfd1cb53"><span data-lake-id="u8cb68b99" id="u8cb68b99">就绪（READY）:线程对象创建后，其他线程(比如main线程）调用了该对象的start()方法。该状态的线程位于可运行线程池中，等待被线程调度选中并分配cpu使用权 。</span></p>
  <p data-lake-id="u629206be" id="u629206be"><span data-lake-id="u9fe1a2b6" id="u9fe1a2b6">运行中（RUNNING）：就绪(READY)的线程获得了cpu 时间片，开始执行程序代码。</span></p>
  <p data-lake-id="u1e8334e1" id="u1e8334e1"><span data-lake-id="u724fc48f" id="u724fc48f">3.阻塞(BLOCKED)：表示线程阻塞于锁（关于锁，在后面章节会介绍）。</span></p>
  <p data-lake-id="u45b5330d" id="u45b5330d"><span data-lake-id="u6e8803da" id="u6e8803da">4.等待(WAITING)：进入该状态的线程需要等待其他线程做出一些特定动作（通知或中断）。</span></p>
  <p data-lake-id="udedc4b41" id="udedc4b41"><span data-lake-id="u0d87bdb9" id="u0d87bdb9">5.超时等待(TIMED_WAITING)：该状态不同于WAITING，它可以在指定的时间后自行返回。</span></p>
  <p data-lake-id="ue89ac357" id="ue89ac357"><span data-lake-id="u816c3896" id="u816c3896">6. 终止(TERMINATED)：表示该线程已经执行完毕。</span></p>
  <p data-lake-id="uded1ba2c" id="uded1ba2c"><span data-lake-id="u9118a7e7" id="u9118a7e7">状态流转如图：</span></p>
  <p data-lake-id="u4b2dd078" id="u4b2dd078"><img src="https://cdn.nlark.com/yuque/0/2023/png/5378072/1703596501381-ac42214e-f6fa-44ce-a54e-20fc90606afb.png?x-oss-process=image%2Fwatermark%2Ctype_d3F5LW1pY3JvaGVp%2Csize_41%2Ctext_SmF2YSA4IEd1IFA%3D%2Ccolor_FFFFFF%2Cshadow_50%2Ct_80%2Cg_se%2Cx_10%2Cy_10"></p>
  <p data-lake-id="u4a2c40de" id="u4a2c40de"><br></p>
  <h1 data-lake-id="QTLUq" id="QTLUq"><span data-lake-id="u5695797d" id="u5695797d">拓展知识</span></h1>
  <p data-lake-id="ubaff2856" id="ubaff2856"><br></p>
  <h2 data-lake-id="pvTzP" id="pvTzP"><span data-lake-id="u10b80949" id="u10b80949">WAITING和TIMED_WAIT的区别？</span></h2>
  <p data-lake-id="ue99ce5c1" id="ue99ce5c1"><span data-lake-id="ucb6f8729" id="ucb6f8729">​</span><br></p>
  <p data-lake-id="u4b0858cd" id="u4b0858cd"><span data-lake-id="uf3116076" id="uf3116076">WAITING是等待状态，在Java中，调用wait方法时，线程会进入到WAITING状态，而TIMED_WAITING是超时等待状态，当线程执行sleep方法时，线程会进入TIMED_WAIT状态。</span></p>
  <p data-lake-id="u0d87a2b1" id="u0d87a2b1"><span data-lake-id="u818e0acb" id="u818e0acb">​</span><br></p>
  <p data-lake-id="u080ee2fd" id="u080ee2fd"><span data-lake-id="u1fabe002" id="u1fabe002">处于WAITING和TIMED_WAIT的线程，都是会让出CPU的，这时候其他线程就可以获得CPU时间片开始执行。但是他们在对象的锁释放上面并不一样，如果加了锁，sleep方法不会释放对象上的锁，而wait方法是会释放锁的。</span></p>
  <p data-lake-id="u7ef74f1b" id="u7ef74f1b"><br></p>
  <p data-lake-id="u7aa54573" id="u7aa54573"><span data-lake-id="uf14e8cd1" id="uf14e8cd1" style="color: rgb(38, 38, 38)"> 因为Java锁的目标是对象，所以wait、notify和notifyAll针对的目标都是对象，所以把他们定义在Object类中。而sleep不需要释放锁，所以他是Thread类中的一个方法。 </span></p>
  <h2 data-lake-id="xBSTu" id="xBSTu"><span data-lake-id="ue8e2af5f" id="ue8e2af5f">为什么线程没有RUNNING状态</span></h2>
  <p data-lake-id="ube1ed968" id="ube1ed968"><span data-lake-id="ud3fad097" id="ud3fad097">对于现在的分时操作系统来说，在单CPU情况下，所有的线程其实都是串行执行的。但是为了让我们看起来像是在并发执行，人们把CPU的执行分成很多个小的时间片。</span></p>
  <p data-lake-id="uaa5887cf" id="uaa5887cf"><span data-lake-id="ub64ee6ef" id="ub64ee6ef">​</span><br></p>
  <p data-lake-id="ue7c3f3fd" id="ue7c3f3fd"><span data-lake-id="u67e6074d" id="u67e6074d">哪个线程得到时间片，那个线程就执行，时间片到了之后，就要释放出CPU，再重新进行争抢时间片。</span></p>
  <p data-lake-id="u099b1efd" id="u099b1efd"><span data-lake-id="u1402eedd" id="u1402eedd">​</span><br></p>
  <p data-lake-id="u495f7473" id="u495f7473"><span data-lake-id="u050abbdf" id="u050abbdf">只要把时间片划分的足够细，那么多个程序虽然在不断的串行执行，但是看起来也像是在同时执行一样。</span></p>
  <p data-lake-id="uc276a4cb" id="uc276a4cb"><span data-lake-id="ue0c78562" id="ue0c78562">​</span><br></p>
  <p data-lake-id="u4f6a8759" id="u4f6a8759"><img src="https://cdn.nlark.com/yuque/0/2022/png/5378072/1665582666549-e9fe6aed-0c0e-4288-8412-4bcc289027f6.png?x-oss-process=image%2Fwatermark%2Ctype_d3F5LW1pY3JvaGVp%2Csize_30%2Ctext_SmF2YSA4IEd1IFA%3D%2Ccolor_FFFFFF%2Cshadow_50%2Ct_80%2Cg_se%2Cx_10%2Cy_10"></p>
  <p data-lake-id="u782081ed" id="u782081ed"><span data-lake-id="ub7672252" id="ub7672252">​</span><br></p>
  <p data-lake-id="u7629ef3e" id="u7629ef3e"><span data-lake-id="ub981bc34" id="ub981bc34">那么，CPU的时间片其实是很短的，一般也就是10-20毫秒左右。</span></p>
  <p data-lake-id="u6095678e" id="u6095678e"><span data-lake-id="uf52783f4" id="uf52783f4">​</span><br></p>
  <p data-lake-id="u256f4bb2" id="u256f4bb2"><span data-lake-id="ub0001f29" id="ub0001f29">那么，也就是说，在一秒钟之内，同一个线程可能一部分时间处于READY状态、一部分时间处于RUNNING状态。</span></p>
  <p data-lake-id="u63984831" id="u63984831"><span data-lake-id="u5c85eb30" id="u5c85eb30">​</span><br></p>
  <p data-lake-id="u6d83a0e2" id="u6d83a0e2"><span data-lake-id="u8c8ace59" id="u8c8ace59">那么如果，明确的给线程定义出RUNNING状态的话，有一个很大的问题，就是这个状态其实是不准的。</span></p>
  <p data-lake-id="u51fe7223" id="u51fe7223"><span data-lake-id="u6dcf5db8" id="u6dcf5db8">​</span><br></p>
  <p data-lake-id="u084577e0" id="u084577e0"><span data-lake-id="udcbb8e58" id="udcbb8e58">因为当我们看到线程是RUNNING状态的时候，很有可能他已经丢失了CPU时间片了。</span></p>
  <p data-lake-id="uf675c7fc" id="uf675c7fc"><span data-lake-id="u186e028f" id="u186e028f">​</span><br></p>
  <p data-lake-id="uf7a22704" id="uf7a22704"><span data-lake-id="u4cad22ac" id="u4cad22ac">对于线程的状态，我们只需要知道，他当前有没有在"正在参与执行"就行了，何为"参与执行"？</span></p>
  <p data-lake-id="ub9e14973" id="ub9e14973"><span data-lake-id="u64f69fbe" id="u64f69fbe">​</span><br></p>
  <p data-lake-id="u9ad0cdad" id="u9ad0cdad"><span data-lake-id="u0888d4bd" id="u0888d4bd">就是他的状态是可执行的，只要获得时间片，就能立即执行。</span></p>
  <p data-lake-id="u847fe17a" id="u847fe17a"><span data-lake-id="u6e037f81" id="u6e037f81">​</span><br></p>
  <p data-lake-id="u55120b8e" id="u55120b8e"><span data-lake-id="uc8b6427c" id="uc8b6427c">那这不就是RUNNABLE吗？</span></p>
  <p data-lake-id="ua12bd85f" id="ua12bd85f"><span data-lake-id="u82814cc4" id="u82814cc4">​</span><br></p>
  <p data-lake-id="u0cd179f3" id="u0cd179f3"><span data-lake-id="u9769ed76" id="u9769ed76">所以，Java就没有给线程定义RUNNING状态，而是定义了一个RUNNABLE状态。</span></p>
  <p data-lake-id="u0fb30e95" id="u0fb30e95"><br></p>
  <p data-lake-id="ud264c7ec" id="ud264c7ec"><br></p>
 </body>
</html>